home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 429_01 / chess12 / chessui.cpp < prev    next >
C/C++ Source or Header  |  1994-04-30  |  14KB  |  604 lines

  1. #include "misc.hpp"
  2. #include "brdsize.hpp"
  3. #include "chess.hpp"
  4. #include "chessui.hpp"
  5. #include "chcharui.hpp"
  6.  
  7. CHESSUSERIFACE ChessUI;
  8.  
  9. const char whiteText[] = "White",
  10.            blackText[] = "Black";
  11.  
  12. LOCAL const char *colorText(PIECECOLOR color)
  13.   { return(color == WHITE ? whiteText : blackText); }
  14.  
  15. // returns piece abbreviation to be displayed in board squares
  16. // for a given piece
  17. LOCAL const char *pieceAbbrev
  18.   (
  19.     PIECECOLOR color,
  20.     PIECETYPE type
  21.   )
  22.   {
  23.     if (color == WHITE)
  24.       switch (type)
  25.         {
  26.     case TYPEKING:   return("WK");
  27.     case TYPEQUEEN:  return("WQ");
  28.     case TYPEBISHOP: return("WB");
  29.     case TYPEKNIGHT: return("WN");
  30.     case TYPEROOK:   return("WR");
  31.     case TYPEPAWN:   return("WP");
  32.     }
  33.     else
  34.       switch (type)
  35.         {
  36.     case TYPEKING:   return("BK");
  37.     case TYPEQUEEN:  return("BQ");
  38.     case TYPEBISHOP: return("BB");
  39.     case TYPEKNIGHT: return("BN");
  40.     case TYPEROOK:   return("BR");
  41.     case TYPEPAWN:   return("BP");
  42.     }
  43.     return(""); // dummy return
  44.   }
  45.  
  46. const char kingText[] = " King",
  47.            queenText[] = " Queen",
  48.            bishopText[] = " Bishop",
  49.            knightText[] = " Knight",
  50.            rookText[] = " Rook",
  51.            pawnText[] = " Pawn";
  52.  
  53. // fills in two entries in a message textList with color/name of
  54. // a piece
  55. LOCAL void pieceText
  56.   (
  57.     PIECECOLOR color,
  58.     PIECETYPE type,
  59.     const char **textList
  60.   )
  61.   {
  62.     *(textList++) = colorText(color);
  63.  
  64.     switch (type)
  65.       {
  66.       case TYPEKING:
  67.     *textList = kingText;
  68.     return;
  69.  
  70.       case TYPEQUEEN:
  71.     *textList = queenText;
  72.     return;
  73.  
  74.       case TYPEBISHOP:
  75.     *textList = bishopText;
  76.     return;
  77.  
  78.       case TYPEKNIGHT:
  79.     *textList = knightText;
  80.     return;
  81.  
  82.       case TYPEROOK:
  83.     *textList = rookText;
  84.     return;
  85.  
  86.       case TYPEPAWN:
  87.     *textList = pawnText;
  88.     return;
  89.       }
  90.   }
  91.  
  92. // base textLists for messages.  terminated by null pointers.  some
  93. // have null pointer place holders for variable portions of message.
  94.  
  95. const char *noMemory[] =
  96.   {
  97.     "Insufficient memory.  Press any key to exit:",
  98.     (char *) 0
  99.   };
  100.  
  101. const char *checkMated[] =
  102.   {
  103.     (char *) 0,
  104.     " King in checkmate.  Press any key to exit:",
  105.     (char *) 0
  106.   };
  107. const int MATEDCOLORINDEX = 0;
  108.  
  109. const char *staleMate[] =
  110.   {
  111.     (char *) 0,
  112.     " King in stalemate.  Press any key to exit:",
  113.     (char *) 0
  114.   };
  115. const int STALEMATEDCOLORINDEX = 0;
  116.  
  117. const char *selectPiece[] =
  118.   {
  119.     (char *) 0,
  120.     " Player:  Select piece to move with arrow keys, then hit enter:",
  121.     (char *) 0
  122.   };
  123. const int SELECTCOLORINDEX = 0;
  124.  
  125. const char *illegalSelection[] =
  126.   {
  127.     "That location does not contain one of your pieces."
  128.     "  Press any key to try again:",
  129.     (char *) 0
  130.   };
  131.  
  132. const char *moveIllegal[] =
  133.   {
  134.     "You cannot move the selected piece to that location."
  135.     "  Press any key to try again:",
  136.     (char *) 0
  137.   };
  138.  
  139. const char *wouldLoseKing[] =
  140.   {
  141.     "This move would result in your King being taken by the ",
  142.     (char *) 0,
  143.     (char *) 0,
  144.     ".  Press any key to select another move:",
  145.     (char *) 0
  146.   };
  147. const int DANGERINDEX = 1;
  148.  
  149. const char *castleQueenRook[] =
  150.   {
  151.     "Do you want to castle with Queen's Rook? (Type Y or N):",
  152.     (char *) 0
  153.   };
  154.  
  155. const char *castleKingRook[] =
  156.   {
  157.     "Do you want to castle with King's Rook? (Type Y or N):",
  158.     (char *) 0
  159.   };
  160.  
  161. const char *selectDest[] =
  162.   {
  163.     "Select destination of move with arrow keys, then hit enter:",
  164.     (char *) 0
  165.   };
  166.  
  167. const char *promoteToWhat[] =
  168.   {
  169.     "Do you want your Pawn to be promoted to a Queen, Bishop, "
  170.     "Knight or Rook?  (Type Q, B, K or R):",
  171.     (char *) 0
  172.   };
  173.  
  174. // character key lists
  175.  
  176. const char promoteOptions[] = "qQbBkKrR";
  177. const PIECETYPE promoteType[] = { TYPEQUEEN, TYPEBISHOP, TYPEKNIGHT,
  178.                                   TYPEROOK };
  179.  
  180. const char yesNoAnswer[] = "yYnN";
  181. const int YESINDEX = 0;
  182. const int NOINDEX = 1;
  183.  
  184. // more message text lists
  185.  
  186. const char *thinking[] =
  187.   {
  188.     (char *) 0,
  189.     " Player thinking, please wait...",
  190.     (char *) 0
  191.   };
  192. const int THINKINGCOLORINDEX = 0;
  193.  
  194. const char *doCastleQueenRook[] =
  195.   {
  196.     (char *) 0,
  197.     " Player castles with Queen's Rook.  Press any key to continue:",
  198.     (char *) 0
  199.   };
  200. const char *doCastleKingRook[] =
  201.   {
  202.     (char *) 0,
  203.     " Player castles with King's Rook.  Press any key to continue:",
  204.     (char *) 0
  205.   };
  206. const int CASTLECOLORINDEX = 0;
  207.  
  208. const char *whatMoved[] =
  209.   {
  210.     (char *) 0,
  211.     " Player moves ",
  212.     (char *) 0,
  213.     (char *) 0,
  214.     ".  Press any key to continue:",
  215.     (char *) 0
  216.   };
  217. const int MOVECOLORINDEX = 0;
  218. const int MOVEPIECEINDEX = 2;
  219.  
  220. const char *whatMovedCaptured[] =
  221.   {
  222.     (char *) 0,
  223.     " Player moves ",
  224.     (char *) 0,
  225.     (char *) 0,
  226.     ", capturing ",
  227.     (char *) 0,
  228.     (char *) 0,
  229.     ".  Press any key to continue:",
  230.     (char *) 0
  231.   };
  232. const int CAPTURINGCOLORINDEX = 0;
  233. const int CAPTURINGPIECEINDEX = 2;
  234. const int CAPTUREDPIECEINDEX = 5;
  235.  
  236. const char *doPromotion[] =
  237.   {
  238.     (char *) 0,
  239.     " Player promotes Pawn to ",
  240.     (char *) 0,
  241.     (char *) 0,
  242.     ".  Press any key to continue:",
  243.     (char *) 0
  244.   };
  245. const int PROMOTECOLORINDEX = 0;
  246. const int PROMOTEPIECEINDEX = 2;
  247.  
  248. void CHESSUSERIFACE::outOfMemory(void)
  249.   {
  250.     ChessCharUI.showMessage(noMemory, (char *) 0, (uint *) 0);
  251.  
  252.     return;
  253.   }
  254.  
  255. void CHESSUSERIFACE::init(const BOARD &board)
  256.   {
  257.     int row, col;
  258.     PIECE *p;
  259.  
  260.     ChessCharUI.initScreen();
  261.  
  262.     for (row = 0; row < NUMROWS; row++)
  263.       for (col = 0; col < NUMCOLS; col++)
  264.     {
  265.       p = board.whatPiece(row, col);
  266.       if (p)
  267.         ChessCharUI.showPiece
  268.           (
  269.         POSITION(row, col),
  270.         pieceAbbrev(p->whatColor(), p->whatType())
  271.           );
  272.     }
  273.  
  274.     return;
  275.   }
  276.  
  277. void CHESSUSERIFACE::mated(PIECECOLOR color)
  278.   {
  279.     checkMated[MATEDCOLORINDEX] = colorText(color);
  280.     ChessCharUI.showMessage(checkMated, (char *) 0, (uint *) 0);
  281.  
  282.     return;
  283.   }
  284.  
  285. void CHESSUSERIFACE::staleMated(PIECECOLOR color)
  286.   {
  287.     staleMate[STALEMATEDCOLORINDEX] = colorText(color);
  288.     ChessCharUI.showMessage(staleMate, (char *) 0, (uint *) 0);
  289.  
  290.     return;
  291.   }
  292.  
  293. BOOL CHESSUSERIFACE::userMove(BOARD &board, PIECECOLOR color)
  294.   {
  295.     POSITION start, end;
  296.     PIECE *p;
  297.     uint keyIndex;
  298.     MOVESTATUS moveStatus;
  299.     MOVEUNDODATA dummy;
  300.  
  301.     selectPiece[SELECTCOLORINDEX] = colorText(color);
  302.  
  303.     // loop to get legal move
  304.     for ( ; ; )
  305.       {
  306.     // loop to get piece to move
  307.     for ( ; ; )
  308.       {
  309.         start.row = start.col = 0;
  310.         if (!ChessCharUI.selectPosition(selectPiece, start))
  311.           return(FALSE);
  312.  
  313.         p = board.whatPiece(start);
  314.         if (p)
  315.           if (p->whatColor() == color)
  316.         break;
  317.  
  318.         if (!ChessCharUI.showMessage(illegalSelection,
  319.                      (char *) 0, (uint *) 0))
  320.           return(FALSE);
  321.  
  322.         ChessCharUI.clearSelect(start);
  323.       }
  324.  
  325.     if (board.userCanCastle(QUEENSIDECASTLE, color))
  326.       if ((p->whatType() == TYPEKING) ||
  327.               ((p->whatType() == TYPEROOK) && (start.row == 0)))
  328.         {
  329.           if (!ChessCharUI.showMessage(castleQueenRook,
  330.                        yesNoAnswer, &keyIndex))
  331.         return(FALSE);
  332.           if ((keyIndex / 2) == YESINDEX)
  333.         {
  334.           ChessCharUI.clearSelect(start);
  335.           board.castle(QUEENSIDECASTLE, color, dummy);
  336.           ChessCharUI.clearPiece(POSITION(0, start.col));
  337.           ChessCharUI.showPiece
  338.             (
  339.               POSITION(3, start.col),
  340.               pieceAbbrev(color, TYPEROOK)
  341.             );
  342.           ChessCharUI.clearPiece(POSITION(4, start.col));
  343.           ChessCharUI.showPiece
  344.             (
  345.               POSITION(2, start.col),
  346.               pieceAbbrev(color, TYPEKING)
  347.             );
  348.           return(TRUE);
  349.         }
  350.         }
  351.  
  352.     if (board.userCanCastle(KINGSIDECASTLE, color))
  353.       if ((p->whatType() == TYPEKING) ||
  354.               ((p->whatType() == TYPEROOK) && (start.row == 7)))
  355.         {
  356.           if (!ChessCharUI.showMessage(castleKingRook,
  357.                        yesNoAnswer, &keyIndex))
  358.         return(FALSE);
  359.           if ((keyIndex / 2) == YESINDEX)
  360.         {
  361.           ChessCharUI.clearSelect(start);
  362.           board.castle(KINGSIDECASTLE, color, dummy);
  363.           ChessCharUI.clearPiece(POSITION(7, start.co